#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

extern "C" {
#include "libavutil/frame.h"
#include "libavutil/mem.h"
#include "libavcodec/avcodec.h"
#include "libavformat/avformat.h"
#include "libswresample/swresample.h"
#include "libswscale/swscale.h"
}

void dec_mp3(char* input, char* output)
{
    av_register_all();
    AVFormatContext *pFormatContext = avformat_alloc_context();
    if (avformat_open_input(&pFormatContext, input, NULL, NULL) != 0) {
        fprintf(stderr, "打开输入文件失败");
        return ;
    }

    if (avformat_find_stream_info(pFormatContext, NULL) < 0) {
        fprintf(stderr, "获取信息失败");
        return;
    }


    FILE* outfile = fopen(output, "wb");
    if (!outfile) {
        //av_free(c);
        exit(1);
    }
    printf("open output_file %s ok\n", output);

    int audio_stream_index = -1;

    for (int i = 0; i < pFormatContext->nb_streams; ++i) {
        if (pFormatContext->streams[i]->codec->codec_type == AVMEDIA_TYPE_AUDIO) {
            audio_stream_index = i;
            break;
        }
    }

    AVCodecContext *pCodecCtx = pFormatContext->streams[audio_stream_index]->codec;

    AVCodec *pCodec = avcodec_find_decoder(pCodecCtx->codec_id);

    if (avcodec_open2(pCodecCtx, pCodec, NULL) < 0) {

    }

    AVPacket *packet = (AVPacket *) av_malloc(sizeof(AVPacket));

    AVFrame *frame;
    frame = av_frame_alloc();

    SwrContext *swrContext = swr_alloc();

    int got_frame;

    uint8_t *out_buffer = (uint8_t *) av_malloc(44100 * 2);

    uint64_t out_ch_layout = AV_CH_LAYOUT_STEREO;

    enum AVSampleFormat out_format = AV_SAMPLE_FMT_S16;

    int out_sample_rate = pCodecCtx->sample_rate;

    swr_alloc_set_opts(swrContext, out_ch_layout, out_format, out_sample_rate,
                       pCodecCtx->channel_layout, pCodecCtx->sample_fmt, pCodecCtx->sample_rate, 0,
                       NULL);

    swr_init(swrContext);


    int out_channals_nb = av_get_channel_layout_nb_channels(AV_CH_LAYOUT_STEREO);

    //env->CallVoidMethod(instance,createAudio,44100,out_channals_nb);


    while (av_read_frame(pFormatContext, packet)>=0) {
        if (packet->stream_index == audio_stream_index) {

            avcodec_decode_audio4(pCodecCtx,frame,&got_frame,packet);

            if (got_frame) {
                printf("解码\n");

                swr_convert(swrContext, &out_buffer, 44100 * 2, (const uint8_t **) frame->data, frame->nb_samples);

                int size = av_samples_get_buffer_size(NULL, out_channals_nb, frame->nb_samples, AV_SAMPLE_FMT_S16, 1);

                fwrite(out_buffer, 1, size, outfile);
                //jbyteArray audio_sample_array = env->NewByteArray(size);

                //env->SetByteArrayRegion(audio_sample_array, 0, size, (const jbyte *) out_buffer);
                //env->CallVoidMethod(instance,playTrack,audio_sample_array,size);
                //env->DeleteLocalRef(audio_sample_array);

            }
        }

    }

    av_frame_free(&frame);
    swr_free(&swrContext);
    avcodec_close(pCodecCtx);
    avformat_close_input(&pFormatContext);
    fclose(outfile);
}


int main(int argc, char* argv[])
{
    //if(argc<2)
    //{
        //printf("usage:dec_mp3 infile\n");
        //return -1;
    //}
    //输入进行解码的mp3文件
    char intput_file[256] = "test.mp3";

    //输出解码后获取到的pcm音频数据文件
    char output_file[256] = "out.pcm";

    if(argc>1)
    {
        strcpy(intput_file, argv[1]);
    }
    if(argc>2)
    {
        strcpy(output_file, argv[2]);
    }


    dec_mp3(intput_file, output_file);

    return 0;
}


